'''
Created on 2017年9月14日

@author: lml
'''
import mnist.input_data as input_data
import tensorflow as tf

mn = input_data.read_data_sets("./", one_hot=True)
with tf.name_scope('input'):
    x = tf.placeholder("float", shape=[None, 784], name='x')
    y_ = tf.placeholder("float", shape=[None, 10], name='label')


def weight_variable(shape, name):
    initial = tf.truncated_normal(shape, stddev=0.1, name=name)
    return tf.Variable(initial, name=name)

def bias_variable(shape, name):
    initial = tf.constant(0.1, shape=shape, name=name)
    return tf.Variable(initial, name=name)

def conv2d(x,W):
    return tf.nn.conv2d(x,W, strides=[1,1,1,1], padding="SAME", name="conv")

def max_pool_22(x):
    return tf.nn.max_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME', name="max_pool")

x_image = tf.reshape(x, [-1, 28, 28 ,1])

## first layer
with tf.name_scope('layer1'):
    w_conv1 = weight_variable([5,5,1,32], name='w')
    b_conv1 = bias_variable([32], name='bias')

h_conv1 = tf.nn.relu(conv2d(x_image, w_conv1) + b_conv1, name="layer1relu")
h_pool1 = max_pool_22(h_conv1)

## second layer
with tf.name_scope('layer2'):
    w_conv2 = weight_variable([5,5,32,64], name='w')
    b_conv2 = bias_variable([64], name='bias')

h_conv2 = tf.nn.relu(conv2d(h_pool1, w_conv2) + b_conv2, name="layer2relu")
h_pool2 = max_pool_22(h_conv2)

## third layer fc
with tf.name_scope('layer3'):
    w_fc1 = weight_variable([7*7*64, 1024], name='w')
    b_fc1 = bias_variable([1024], name='bias')

h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, w_fc1) + b_fc1, name="layer3relu");

keep_prob = tf.placeholder("float")
h_fc1_dropout = tf.nn.dropout(h_fc1, keep_prob, name="dropout")

## forth softmax
with tf.name_scope('soft_max'):
    w_fc2 = weight_variable([1024, 10], name='w')
    b_fc2 = bias_variable([10], name='bias')
    
y_conv = tf.nn.softmax(tf.matmul(h_fc1_dropout, w_fc2)+ b_fc2, name="softmax")

with tf.name_scope('result'):
    cross_entropy = -tf.reduce_sum(y_ * tf.log(y_conv), name='cross_entropy')
    tf.summary.scalar('loss', cross_entropy)
    train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
    correct_prediction = tf.equal(tf.argmax(y_conv, 1), tf.arg_max(y_, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"), name='accuracy')
    tf.summary.scalar('accuracy', accuracy)

init = tf.initialize_all_variables()
sess = tf.Session()
summary_op = tf.summary.merge_all()
summary_writer = tf.summary.FileWriter("./tmp", sess.graph)
sess.run(init)

print(sess.graph.get_all_collection_keys())
print(sess.graph.get_operations())

for i in range(20000):
    batch = mn.train.next_batch(100)
    sess.run(train_step, feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})
    if i % 100 == 0:
#         train_accuracy = accuracy.eval(feed_dict={x:batch[0], y_:batch[1], keep_prob:1.0})
#         print("step %d, training accuracy %g"%(i, train_accuracy))
        summary_result = sess.run(summary_op, feed_dict={x:batch[0], y_:batch[1], keep_prob:1.0})
        summary_writer.add_summary(summary_result, i)
        print("step: %i"%i)
    
print ("test accuracy %g"%accuracy.eval(feed_dict={
    x: mn.test.images, y_: mn.test.labels, keep_prob: 1.0}))
